package com.itheima.d2_upd1;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
 * 目标：完成UDP通信快速入门-服务端开发
 *      模拟服务端
 *
 *   必须先启动服务端，然后启动客户端发送的数据包才会能够接收到。
 *          假如先启动客户端，也没有抛出异常，也没有服务端接，数据包就这样丢掉了
 *
 *   启动服务端后，程序会卡在socket.receive(packet);这里，然后启动客户端把数据包发过来
 */
public class Server {
    public static void main(String[] args) throws Exception {
        /*
        DatagramSocket用于创建服务端的构造器：
        public DatagramSocket(int port)  创建服务端的Socket对象, 并指定端口号
        DatagramSocket方法：
        public void receive(DatagramPacket p)    使用数据包接收数据

        DatagramPacket创建数据包的构造器：
        public DatagramPacket(byte[] buf, int length)    创建用来接收数据的数据包
         */

        System.out.println("----服务端启动----");
        // 1、创建一个服务端对象（创建一个接韭菜的人） 注册端口
        //public DatagramSocket(int port)          创建服务端的Socket对象, 并指定端口号
        DatagramSocket socket = new DatagramSocket(6666);   //直接抛出异常

        // 2、创建一个数据包对象，用于接收数据的（创建一个韭菜盘子）
        //public DatagramPacket(byte[] buf, int length)      创建用来接收数据的数据包
        //两个参数分别是：接一个字节数组充当数据包，接一个数据包的大小
        byte[] buffer = new byte[1024 * 64]; // 64KB.UDP协议规定数据限制在64KB内，所以接收数据的服务端数据包大小设置在64kb就行
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        // 3、开始正式使用数据包来接收客户端发来的数据
        //public void receive(DatagramPacket p)    使用数据包接收数据
        socket.receive(packet);

        // 4、从数据包字节数组中，把接收到的数据直接打印出来
        // 因为定义的字节数组是64kb的，而实际客户端发的数据可能不到1kb，所以直接输出字节数组会有很多其他的内容
        // 接收多少就倒出多少，获取本次数据包接收了多少数据。
        //public int getLength()       获取数据包，实际接收到的字节个数
        int len = packet.getLength();

        String rs = new String(buffer, 0 , len);
        System.out.println(rs);

        //服务端不仅在数据包中可以接收到客户端发过来的数据，还可以接到客户端的ip和客户端的端口
        /*源码：首先拿到InetAddress对象
        public synchronized InetAddress getAddress() {return address;}
            然后通过InetAddress对象的常用方法getHostAddress方法获取IP地址
        public String getHostAddress()  获取该ip地址对象中的ip地址信息
         */
        System.out.println("客户端的ip地址信息： "+packet.getAddress().getHostAddress());
        //获取客户端的端口
        System.out.println("客户端的端口号： "+packet.getPort());

        socket.close(); // 释放资源
    }
}
